<template>
   <div class="app-container">
      <a-row :gutter="20">
         <!--部门数据-->
         <a-col :sm="4" :xs="24">
            <div class="head-container">
               <a-input
                  v-model:value="deptName"
                  placeholder="请输入部门名称"
                  allowClear
                  style="margin-bottom: 20px"
               >
                 <template #prefix>
                   <search-outlined style="color: rgba(0, 0, 0, 0.45)" />
                 </template>
               </a-input>
            </div>
            <div class="head-container">
              <a-directory-tree
                  ref="deptTreeRef"
                  v-if="effectiveDeptOptions.length"
                  :tree-data="effectiveDeptOptions"
                  :show-icon="false"
                  :expandAction="false"
                  :fieldNames="{ title: 'label', children: 'children', key:'id' }"
                  @select="handleNodeClick"
                  :expandedKeys="handleExpandedKeys"
              ></a-directory-tree>
            </div>
         </a-col>
         <!--用户数据-->
         <a-col :sm="20" :xs="24">
           <a-space direction="vertical" size="middle">
             <a-form layout="inline" :labelWrap="true" :model="queryParams" ref="queryRef" v-show="showSearch">
               <a-row :gutter="[0, 16]" >
                 <a-form-item label="用户名称" name="userName">
                   <a-input
                       v-model:value="queryParams.userName"
                       placeholder="请输入用户名称"
                       allowClear
                       style="width: 240px"
                       @keyup.enter="handleQuery"
                   />
                 </a-form-item>
                 <a-form-item label="手机号码" name="phonenumber">
                   <a-input
                       v-model:value="queryParams.phonenumber"
                       placeholder="请输入手机号码"
                       allowClear
                       style="width: 240px"
                       @keyup.enter="handleQuery"
                   />
                 </a-form-item>
                 <a-form-item label="状态" name="status">
                   <a-select
                       v-model:value="queryParams.status"
                       placeholder="用户状态"
                       allowClear
                       style="width: 240px"
                   >
                     <a-select-option
                         v-for="dict in sys_normal_disable"
                         :key="dict.value"
                         :value="dict.value"
                     >{{dict.label}}</a-select-option>
                   </a-select>
                 </a-form-item>
                 <a-form-item label="创建时间" style="width: 308px;">
                   <a-range-picker
                       v-model:value="dateRange"
                       format="YYYY-MM-DD"
                       :placeholder="['开始日期', '结束日期']"
                   ></a-range-picker>
                 </a-form-item>
                 <a-form-item>
                   <a-space>
                     <a-button type="primary" @click="handleQuery"><template #icon><SearchOutlined /></template>搜索</a-button>
                     <a-button @click="resetQuery"><template #icon><sync-outlined /></template>重置</a-button>
                   </a-space>
                 </a-form-item>
               </a-row>
             </a-form>

             <a-row type="flex">
               <a-col flex="auto"><a-space>
                 <a-button
                     type="primary"
                     @click="handleAdd"
                     v-hasPermi="['system:user:add']"
                 ><template #icon><plus-outlined /></template>新增</a-button>
                 <a-button
                     :disabled="single"
                     @click="handleUpdate"
                     v-hasPermi="['system:user:edit']"
                 ><template #icon><form-outlined /></template>修改</a-button>
                 <a-button
                     danger
                     :disabled="multiple"
                     @click="handleDelete"
                     v-hasPermi="['system:user:remove']"
                 ><template #icon><delete-outlined /></template>删除</a-button>
                 <a-button
                     @click="handleImport"
                     v-hasPermi="['system:user:import']"
                 ><template #icon><upload-outlined /></template>导入</a-button>
                 <a-button
                     @click="handleExport"
                     v-hasPermi="['system:user:export']"
                 ><template #icon><download-outlined /></template>导出</a-button>
               </a-space></a-col>
               <a-col flex="100px">
                 <right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
               </a-col>
             </a-row>

             <a-table
                 :loading="loading"
                 :row-key="record => record.userId"
                 :data-source="userList"
                 :columns="effectiveColumns"
                 :pagination="false"
                 :row-selection="{ selectedRowKeys: ids, onChange: handleSelectionChange }"
             >
               <template #bodyCell="{ column, text , record }">
                 <template v-if="column.dataIndex === 'status'">
                   <a-switch
                       v-model:checked="record.status"
                       checkedValue="0"
                       unCheckedValue="1"
                       @change="handleStatusChange(record)"
                   ></a-switch>
                 </template>
                 <template v-if="column.dataIndex === 'dept.deptName'">
                   {{ record.dept?.deptName }}
                 </template>
                 <template v-if="column.dataIndex === 'createTime'">
                   <span>{{ parseTime(record.createTime) }}</span>
                 </template>
                 <template v-if="column.dataIndex === 'operation'">
                   <a-tooltip class="item" title="修改" placement="top" v-if="record.userId !== 1">
                     <a-button type="link" @click="handleUpdate(record)" v-hasPermi="['system:user:edit']">
                       <template #icon><form-outlined /></template>
                     </a-button>
                   </a-tooltip>
                   <a-tooltip title="删除" placement="top" v-if="record.userId !== 1">
                     <a-button type="link" danger @click="handleDelete(record)" v-hasPermi="['system:user:remove']">
                       <template #icon><delete-outlined /></template>
                     </a-button>
                   </a-tooltip>
                   <a-tooltip title="重置密码" placement="top" v-if="record.userId !== 1">
                     <a-button type="link" @click="handleResetPwd(record)" v-hasPermi="['system:user:resetPwd']">
                       <template #icon><key-outlined /></template>
                     </a-button>
                   </a-tooltip>
                   <a-tooltip title="分配角色" placement="top" v-if="record.userId !== 1">
                     <a-button type="link" @click="handleAuthRole(record)" v-hasPermi="['system:user:edit']">
                       <template #icon><check-circle-outlined /></template>
                     </a-button>
                   </a-tooltip>
                 </template>
               </template>
             </a-table>
           </a-space>
            <pagination
               v-show="total > 0"
               :total="total"
               v-model:page="queryParams.pageNum"
               v-model:limit="queryParams.pageSize"
               @pagination="getList"
            />
         </a-col>
      </a-row>

      <!-- 添加或修改用户配置对话框 -->
      <a-modal :title="title" v-model:visible="open" width="600px">
         <a-form :model="form" :rules="rules" ref="userRef" :labelCol="{ style: 'width: 80px' }">
            <a-row :gutter="20">
               <a-col :span="12">
                  <a-form-item label="用户昵称" name="nickName">
                     <a-input v-model:value="form.nickName" placeholder="请输入用户昵称" :maxlength="30" />
                  </a-form-item>
               </a-col>
               <a-col :span="12">
                  <a-form-item label="归属部门" name="deptId">
                     <a-tree-select
                        v-model:value="form.deptId"
                        :tree-data="deptOptions"
                        :fieldNames="{ value: 'id', label: 'label', children: 'children' }"
                        placeholder="请选择归属部门"
                     />
                  </a-form-item>
               </a-col>
              <a-col :span="12">
                <a-form-item label="手机号码" name="phonenumber">
                  <a-input v-model:value="form.phonenumber" placeholder="请输入手机号码" :maxlength="11" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="邮箱" name="email">
                  <a-input v-model:value="form.email" placeholder="请输入邮箱" :maxlength="50" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item v-if="!form.userId" label="用户名称" name="userName">
                  <a-input v-model:value="form.userName" placeholder="请输入用户名称" :maxlength="30" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item v-if="!form.userId" label="用户密码" name="password">
                  <a-input-password v-model:value="form.password" placeholder="请输入用户密码" :maxlength="20" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="用户性别">
                  <a-select v-model:value="form.sex" placeholder="请选择">
                    <a-select-option
                        v-for="dict in sys_user_sex"
                        :key="dict.value"
                        :value="dict.value"
                    >{{ dict.label }}</a-select-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="状态">
                  <a-radio-group v-model:value="form.status">
                    <a-radio
                        v-for="dict in sys_normal_disable"
                        :key="dict.value"
                        :value="dict.value"
                    >{{ dict.label }}</a-radio>
                  </a-radio-group>
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="岗位">
                  <a-select v-model:value="form.postIds" mode="multiple" placeholder="请选择">
                    <a-select-option
                        v-for="item in postOptions"
                        :key="item.postId"
                        :value="item.postId"
                        :disabled="item.status === 1"
                    >{{ item.postName }}</a-select-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="角色">
                  <a-select v-model:value="form.roleIds" mode="multiple" placeholder="请选择">
                    <a-select-option
                        v-for="item in roleOptions"
                        :key="item.roleId"
                        :value="item.roleId"
                        :disabled="item.status === 1"
                    >{{ item.roleName }}</a-select-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :span="24">
                <a-form-item label="备注">
                  <a-textarea v-model:value="form.remark" placeholder="请输入内容"></a-textarea>
                </a-form-item>
              </a-col>
            </a-row>
         </a-form>
         <template #footer>
            <div class="dialog-footer">
               <a-button type="primary" @click="submitForm">确定</a-button>
               <a-button @click="cancel">取消</a-button>
            </div>
         </template>
      </a-modal>

      <!-- 用户导入对话框 -->
      <a-modal
          :title="upload.title"
          v-model:visible="upload.open"
          width="400px"
      >
         <a-upload-dragger
            ref="uploadRef"
            :maxCount="1"
            accept=".xlsx, .xls"
            :file-list="upload.fileList"
            :before-upload="beforeUpload"
            @remove="handleRemove"
            :disabled="upload.isUploading"
         >
           <p class="ant-upload-drag-icon">
             <inbox-outlined></inbox-outlined>
           </p>
           <p class="ant-upload-hint">将文件拖到此处，或<em>点击上传</em></p>
         </a-upload-dragger>
        <div style="text-align: center">
          <div>
            <a-checkbox v-model:checked="upload.updateSupport" />是否更新已经存在的用户数据
          </div>
          <span>仅允许导入xls、xlsx格式文件。</span>
          <a-button type="link" @click="importTemplate">下载模板</a-button>
        </div>
        <template #footer>
          <a-button type="primary" :disabled="upload.fileList.length === 0" @click="handleUpload">确定</a-button>
        </template>
      </a-modal>
   </div>
</template>

<script setup name="User">
import { getToken } from "@/utils/auth";
import { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser, deptTreeSelect } from "@/api/system/user";
import { treeFilter, treeId } from "@/utils/ruoyi";
import { uploadServer } from "@/api/system/upload";

const router = useRouter();
const { proxy } = getCurrentInstance();
const { sys_normal_disable, sys_user_sex } = proxy.useDict("sys_normal_disable", "sys_user_sex");

const userList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const dateRange = ref([]);
const deptName = ref("");
const deptOptions = ref([]);
const initPassword = ref(undefined);
const postOptions = ref([]);
const roleOptions = ref([]);
/*** 用户导入参数 */
const upload = reactive({
  // 是否显示弹出层（用户导入）
  open: false,
  // 弹出层标题（用户导入）
  title: "",
  // 是否禁用上传
  isUploading: false,
  // 是否更新已经存在的用户数据
  updateSupport: 0,
  // 设置上传的请求头部
  headers: { Authorization: "Bearer " + getToken() },
  // 上传的地址
  url: import.meta.env.VITE_APP_BASE_API + "/system/user/importData",
  // 上传文件
  fileList: [],
});
// 列显隐信息
const columns = ref([
  { key: 0, title: `用户编号`, dataIndex: 'userId', visible: true },
  { key: 1, title: `用户名称`, dataIndex: 'userName', ellipsis: true, visible: true },
  { key: 2, title: `用户昵称`, dataIndex: 'nickName', ellipsis: true, visible: true },
  { key: 3, title: `部门`, dataIndex: 'dept.deptName', visible: true },
  { key: 4, title: `手机号码`, dataIndex: 'phonenumber', width: 120, visible: true },
  { key: 5, title: `状态`, dataIndex: 'status', visible: true },
  { key: 6, title: `创建时间`, dataIndex: 'createTime', visible: true },
  { key: 7, title: `操作`, dataIndex: 'operation', visible: true },
])
const effectiveColumns = computed(() => {
  return columns.value.filter(item => item.visible)
})

const data = reactive({
  form: {},
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    userName: undefined,
    phonenumber: undefined,
    status: undefined,
    deptId: undefined
  },
  rules: {
    userName: [{ required: true, message: "用户名称不能为空", trigger: "blur" }, { min: 2, max: 20, message: "用户名称长度必须介于 2 和 20 之间", trigger: "blur" }],
    nickName: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
    password: [{ required: true, message: "用户密码不能为空", trigger: "blur" }, { min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" }],
    email: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }],
    phonenumber: [{ pattern: /^1[3456789][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }]
  }
});

const { queryParams, form, rules } = toRefs(data);

const effectiveDeptOptions = computed(() => {
  if (!deptName.value) {
    return deptOptions.value
  }
  return treeFilter(deptOptions.value, deptName.value);
})
const handleExpandedKeys = computed(() => {
  return treeId(effectiveDeptOptions.value)
})
/** 查询部门下拉树结构 */
function getDeptTree() {
  deptTreeSelect().then(response => {
    deptOptions.value = response.data;
  });
}
/** 查询用户列表 */
function getList() {
  loading.value = true;
  listUser(proxy.addDateRange(queryParams.value, dateRange.value)).then(res => {
    loading.value = false;
    userList.value = res.rows;
    total.value = res.total;
  });
}
/** 节点单击事件 */
function handleNodeClick(selectedKeys) {
  queryParams.value.deptId = selectedKeys[0];
  handleQuery();
}
/** 搜索按钮操作 */
function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
}
/** 重置按钮操作 */
function resetQuery() {
  dateRange.value = [];
  proxy.resetForm("queryRef");
  queryParams.value.deptId = undefined;
  proxy.$refs.tree.setCurrentKey(null);
  handleQuery();
}
/** 删除按钮操作 */
function handleDelete(row) {
  const userIds = row.userId || ids.value;
  proxy.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项？').then(function () {
    return delUser(userIds);
  }).then(() => {
    getList();
    proxy.$modal.msgSuccess("删除成功");
  }).catch(() => {});
}
/** 导出按钮操作 */
function handleExport() {
  proxy.download("system/user/export", {
    ...queryParams.value,
  },`user_${new Date().getTime()}.xlsx`);
}
/** 用户状态修改  */
function handleStatusChange(row) {
  let text = row.status === "0" ? "启用" : "停用";
  proxy.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?').then(function () {
    return changeUserStatus(row.userId, row.status);
  }).then(() => {
    proxy.$modal.msgSuccess(text + "成功");
  }).catch(function () {
    row.status = row.status === "0" ? "1" : "0";
  });
}
/** 跳转角色分配 */
function handleAuthRole(row) {
  const userId = row.userId;
  router.push("/system/user-auth/role/" + userId);
}
/** 重置密码按钮操作 */
function handleResetPwd(row) {
  proxy.$modal.prompt('请输入"' + row.userName + '"的新密码', "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    closeOnClickModal: false,
    inputPattern: /^.{5,20}$/,
    inputErrorMessage: "用户密码长度必须介于 5 和 20 之间",
    onOk: ({value}) => {
      return resetUserPwd(row.userId, value).then(response => {
        proxy.$modal.msgSuccess("修改成功，新密码是：" + value);
      });
    }
  })
}
/** 选择条数  */
function handleSelectionChange(selectedRowKeys) {
  ids.value = selectedRowKeys;
  single.value = selectedRowKeys.length !== 1;
  multiple.value = !selectedRowKeys.length;
}
/** 导入按钮操作 */
function handleImport() {
  upload.title = "用户导入";
  upload.open = true;
}
/** 下载模板操作 */
function importTemplate() {
  proxy.download("system/user/importTemplate", {
  }, `user_template_${new Date().getTime()}.xlsx`);
}
// 文件上传
const handleRemove = file => {
  const index = upload.fileList.indexOf(file);
  const newFileList = upload.fileList.slice();
  newFileList.splice(index, 1);
  upload.fileList = newFileList;
}

const beforeUpload = file => {
  upload.fileList = [file];
  return false;
}

const handleUpload = () => {
  const formData = new FormData();
  upload.fileList.forEach((file) => {
    formData.append('file', file)
  });
  upload.isUploading = true;

  uploadServer(formData, upload.updateSupport)
      .then(() => {
        upload.fileList = [];
        upload.isUploading = false;
        proxy.$modal.msgSuccess("上传成功");
      })
      .catch(() => {
        upload.isUploading = false;
        proxy.$modal.msgError("上传失败");
      });
}
/** 重置操作表单 */
function reset() {
  form.value = {
    userId: undefined,
    deptId: undefined,
    userName: undefined,
    nickName: undefined,
    password: undefined,
    phonenumber: undefined,
    email: undefined,
    sex: undefined,
    status: "0",
    remark: undefined,
    postIds: [],
    roleIds: []
  }
  proxy.resetForm("userRef");
}
/** 取消按钮 */
function cancel() {
  open.value = false;
  reset();
}
/** 新增按钮操作 */
function handleAdd() {
  reset();
  getUser().then(response => {
    postOptions.value = response.data.posts;
    roleOptions.value = response.data.roles;
    open.value = true;
    title.value = "添加用户";
    form.value.password = initPassword.value;
  });
}
/** 修改按钮操作 */
function handleUpdate(row) {
  reset();
  const userId = row.userId || ids.value;
  getUser(userId).then(response => {
    form.value = response.data.user;
    postOptions.value = response.data.posts;
    roleOptions.value = response.data.roles;
    form.value.postIds = response.data.postIds;
    form.value.roleIds = response.data.roleIds;
    open.value = true;
    title.value = "修改用户";
    form.password = "";
  });
}
/** 提交按钮 */
function submitForm() {
  proxy.$refs["userRef"].validate().then(() => {
    if (form.value.userId) {
      updateUser(form.value).then(response => {
        proxy.$modal.msgSuccess("修改成功");
        open.value = false;
        getList();
      });
    } else {
      addUser(form.value).then(response => {
        proxy.$modal.msgSuccess("新增成功");
        open.value = false;
        getList();
      });
    }
  });
}

getDeptTree();
getList();
</script>
